package phase3Specification.testing;

import dbPhase.hypeerweb.HyPeerWeb;
import dbPhase.hypeerweb.HyPeerWebDatabase;
import dbPhase.hypeerweb.Node;
import dbPhase.hypeerweb.SimplifiedNodeDomain;
//import dbPhase.hypeerweb.WebId;
import phase2Specification.testing.hypeerweb.ExpectedResult;

public class Exp {
    public static HyPeerWeb hypeerweb = null;
    private static final int PHASE_3_TEST_COUNT = 10912;
    private static int errorCount = 0;

    public static void main(String[] args) {
        HyPeerWebDatabase.initHyPeerWebDatabase();
        HyPeerWebDatabase.getSingleton().clear();
        hypeerweb = HyPeerWeb.getSingleton();
        testPhase3();
    }
    
    static private void testPhase3() {
        System.out.println("\nTesting Phase 3");
        hypeerweb.clear();
        errorCount = 0;
        int testnum=0;
        
        boolean insertionError = false;
        System.out.print("    ");
        
        for (int size = HYPEERWEB_SIZE; size >= 2; size--) {
            if(VERBOSE) {
                System.out.println("Testing Node Insertion on HyPeerWeb of size " + size + "/" + HYPEERWEB_SIZE);
            } else {
                System.out.print(size + " ");
            }

            for (int deletedNodeId = 0; deletedNodeId < size; deletedNodeId++) {
                createHyPeerWebWith(size);
                
                Node deletionNode = hypeerweb.getNode(deletedNodeId);
                deletionNode.removeFromHyPeerWeb();
                testnum++;
                
                for (int i = 0; i < size - 1; i++) {
                //	System.out.println("Test#"+ testnum);
                	
                    Node nodei = hypeerweb.getNode(i);
                    SimplifiedNodeDomain simplifiedNodeDomain = nodei.constructSimplifiedNodeDomain();
                    ExpectedResult expectedResult = new ExpectedResult(size - 1, i);

                    if (!simplifiedNodeDomain.equals(expectedResult)) {
                        insertionError = true;
                        System.out.println("DeletionNode is: "+ deletedNodeId);
                        printErrorMessage(size, deletionNode, simplifiedNodeDomain, expectedResult);
                        errorCount++;
                    }
                }
            }
        }
        if(!VERBOSE){
            System.out.println();
        }
        
        if (insertionError) {
            double decimalPercent = ((double)PHASE_3_TEST_COUNT - (double) errorCount) / (double) PHASE_3_TEST_COUNT;
            int integerPercent = (int) (decimalPercent * 100.0d);
            System.out.println("Error Count: "+ errorCount);
            System.out.println("    Insertion Error: Phase 3 Score = " + integerPercent + "%");
        } else {
            System.out.println("    No Insertion Errors: Phase 3 Score = 100%");
        }
    }
    
    private static void printErrorMessage(int size, Node startNode, SimplifiedNodeDomain simplifiedNodeDomain, ExpectedResult expectedResult) {
        errorCount++;

        System.out.println("-------------------------------------------------------------");
        System.out.println("INSERTION ERROR when HyPeerWebSize = " + size); // + ", Start Location: " + startNode);
        System.out.println("Node Information:");
        System.out.println(simplifiedNodeDomain);
        System.out.println();
        System.out.println("Expected Information");
        System.out.println(expectedResult);
    }

    static private void createHyPeerWebWith(int numberOfNodes) {
        hypeerweb.clear();
        Node node0 = new Node(0);
        hypeerweb.addToHyPeerWeb(node0, null);

        for (int i = 1; i < numberOfNodes; i++) {
            Node node = new Node(0);
            node0.addToHyPeerWeb(node);
        }
    }
    
    private static final int HYPEERWEB_SIZE = 16;
    private static final boolean VERBOSE = false;
}